#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <time.h>

#include "yarn.h"

#ifndef YARN_MAP_COUNT
#define YARN_MAP_COUNT 256 // Has to be a power-of-two
#endif
#define YARN_MAP_MASK (YARN_MAP_COUNT - 1)

struct yarn_state
{
    char *code;              // The code that we will execute 将要执行的指令存放内存区域，使用malloc申请空间地址
    size_t codesize;         // The code size 申请大的空间大小
    void *memory;            // Memory for the program. Contains registers, flags, everything 为程序申请的内存空间，包括寄存器，标志位，和其他用途
    size_t memsize;          // The total size of memory 总申请的内存空间大小
    size_t instructioncount; // Total count of instuctions used 总的指令条数
    // Sys call hash map data structure: 系统调用映射为一个结构体
    struct
    {
        unsigned key;   // 键
        yarn_CFunc val; // 值
    } syscalls[YARN_MAP_COUNT];
};

// Syscalls:
// 以下是系统调用支持的函数
static void yarn_sys_gettime(yarn_state *Y) // 获取系统时间
{
    yarn_int t = time(NULL);
    yarn_setRegister(Y, YARN_REG_RETURN, &t);
}
static void yarn_sys_getinstructioncount(yarn_state *Y) // 获取指令条数
{
    yarn_setRegister(Y, YARN_REG_RETURN, &Y->instructioncount);
}
static void yarn_sys_getvmmemory(yarn_state *Y) // 获取虚拟机内存容量
{
    yarn_setRegister(Y, YARN_REG_RETURN, &Y->memsize);
}

// yarn_functions
// 虚拟机函数
yarn_state *yarn_init(size_t memsize) // 初始化虚拟机
{
    yarn_uint stackaddr;                        // 栈地址
    yarn_uint instaddr;                         // 指令地址
    yarn_state *Y = malloc(sizeof(yarn_state)); // 初始化虚拟机内存空间
    if (Y == NULL)
    {
        return NULL;
    }
    Y->code = NULL;
    Y->memsize = memsize;           // 设置虚拟机内存大小
    Y->memory = calloc(memsize, 1); // 给当前虚拟机分配memsize个大小的字节空间
    if (Y->memory == NULL)          // 分配失败
    {
        free(Y); // 释放空间
        return NULL;
    }

    //Init our instruction pointer to 0
    instaddr = 0;                                         // 初始指令地址为0,意思是从第一行开始读取指令
    yarn_setRegister(Y, YARN_REG_INSTRUCTION, &instaddr); // 根据这个指令指针设置指令寄存器的值

    // Init our stack&base pointer to the top of the memory, stack will grow down.
    //   Leave space for the registers, flags, and other stuff at the top.
    // 基址地址和栈地址一致，当前指向栈顶，栈向上增长
    // 多留两个空间的原因是给flag和其他成员使用
    stackaddr = memsize - (YARN_REG_NUM + 2) * sizeof(yarn_uint); // 除了虚拟机寄存器占用的空间，剩余空间都设置为栈空间
    yarn_setRegister(Y, YARN_REG_STACK, &stackaddr);              // 设置栈指针寄存器
    yarn_setRegister(Y, YARN_REG_BASE, &stackaddr);               // 设置基址寄存器

    struct
    {
        yarn_uint id;
        yarn_CFunc fn;
    } syscalls[] = {// 初始化系统调用
                    {0x00, yarn_sys_getvmmemory},
                    {0x01, yarn_sys_getinstructioncount},
                    {0x02, yarn_sys_gettime},
                    {0x00, NULL}};
    for (int i = 0; syscalls[i].fn; i++) // 变量这个数组，分别注册每一个系统调用
    {
        yarn_registerSysCall(Y, syscalls[i].id, syscalls[i].fn); // 参数是当前虚拟机实例和系统调用ID和其映射的函数名
    }

    return Y;
}

void yarn_destroy(yarn_state *Y) // 销毁虚拟机
{
    free(Y->code);   // 释放代码段空间
    free(Y->memory); // 释放虚拟机申请运行时所需空间
    free(Y);         // 释放虚拟机结构体本身
}

// Will copy given code to an internal buffer.
int yarn_loadCode(yarn_state *Y, char *code, size_t codesize) // 加载代码指令到虚拟机内部缓冲区
{
    free(Y->code); // 不管虚拟机当前保存指令代码区域的空间是否为空，先释放

    Y->code = malloc(codesize); // 申请指定大小的代码存储空间
    if (Y->code == NULL)
    {
        return -1;
    }
    memcpy(Y->code, code, codesize); // 申请到的空间拷贝到虚拟机存储指令代码的区域
    Y->codesize = codesize;          // 设置当前区域指令代码大小
    return 0;
}

// Returns the pointer to its memory.
void *yarn_getMemoryPtr(yarn_state *Y) // 获取内存指针
{
    return Y->memory; // 返回当前虚拟机的内存指针
}
size_t yarn_getMemorySize(yarn_state *Y) // 获取内存大小
{
    return Y->memsize; // 返回当前虚拟机内存区域大小
}
size_t yarn_getInstructionCount(yarn_state *Y) // 获取指令条数
{
    return Y->instructioncount; // 返回当前虚拟机执行到的指令索引
}

const char *yarn_registerToString(unsigned char reg) // 将寄存器转换为字符串
{                                                    // 寄存器使用数字表示的，这里转换成字符串，方便人类可读
    const char *result;
    switch (reg)
    {
    case YARN_REG_INSTRUCTION:
        result = "%ins";
        break;
    case YARN_REG_STACK:
        result = "%stk";
        break;
    case YARN_REG_BASE:
        result = "%bse";
        break;
    case YARN_REG_RETURN:
        result = "%ret";
        break;
    case YARN_REG_C1:
        result = "%C1";
        break;
    case YARN_REG_C2:
        result = "%C2";
        break;
    case YARN_REG_C3:
        result = "%C3";
        break;
    case YARN_REG_C4:
        result = "%C4";
        break;
    case YARN_REG_C5:
        result = "%C5";
        break;
    case YARN_REG_C6:
        result = "%C6";
        break;
    case YARN_REG_S1:
        result = "%S1";
        break;
    case YARN_REG_S2:
        result = "%S2";
        break;
    case YARN_REG_S3:
        result = "%S3";
        break;
    case YARN_REG_S4:
        result = "%S4";
        break;
    case YARN_REG_S5:
        result = "%S5";
        break;
    case YARN_REG_NULL:
        result = "%null";
        break;
    default:
        result = "invalid";
    }
    return result;
}

const char *yarn_statusToString(int status) // 将数字表示的状态转换为字符串
{
    const char *result;
    switch (status)
    {
    case YARN_STATUS_OK:
        result = "ok";
        break;
    case YARN_STATUS_HALT:
        result = "halt";
        break;
    case YARN_STATUS_PAUSE:
        result = "paused";
        break;
    case YARN_STATUS_INVALIDMEMORY:
        result = "invalid memory access error";
        break;
    case YARN_STATUS_INVALIDINSTRUCTION:
        result = "invalid instruction error";
        break;
    case YARN_STATUS_DIVBYZERO:
        result = "divide by zero  error";
        break;
    default:
        result = "invalid";
    }
    return result;
}

// Shortcuts for register manipulation
#define registerLocation(r) Y->memsize - (yarn_uint)(r + 2) * sizeof(yarn_uint)
// 根据寄存器的编号寻找在内存中的位置
void yarn_getRegister(yarn_state *Y, unsigned char reg, void *val) // 获取寄存器
{
    yarn_getMemory(Y, registerLocation(reg), val, sizeof(yarn_uint)); // 获取内存
}
void yarn_setRegister(yarn_state *Y, unsigned char reg, void *val) // 设置寄存器
{
    yarn_setMemory(Y, registerLocation(reg), val, sizeof(yarn_uint)); // 设置内存
}
void yarn_incRegister(yarn_state *Y, unsigned char reg, yarn_int val) // 自增累加寄存器
{
    yarn_int rval = 0;
    yarn_getRegister(Y, reg, &rval);
    rval += val;
    yarn_setRegister(Y, reg, &rval);
}
#undef registerLocation

// Memory manipulations.
void yarn_getMemory(yarn_state *Y, yarn_uint pos, void *val, size_t bsize) // 获取内存
{
    // 根据用户传入的指针，将指定内存区域拷贝到这个指针上
    if ((pos + bsize) > Y->memsize)
    { // Check for out-of-bounds
        yarn_setStatus(Y, YARN_STATUS_INVALIDMEMORY);
        return;
    }
    memcpy(val, ((char *)Y->memory) + pos, bsize);
}
void yarn_setMemory(yarn_state *Y, yarn_uint pos, void *val, size_t bsize) // 设置内存
{
    // 根据用户传入的地址指针，将该指针对应区域的内容拷贝到虚拟机指定内存区域
    if ((pos + bsize) > Y->memsize) // 判断是否访问越界
    { // Check for out-of-bounds
        yarn_setStatus(Y, YARN_STATUS_INVALIDMEMORY);
        return;
    }
    memcpy(((char *)Y->memory) + pos, val, bsize);
}

// Pushs the stack
void yarn_push(yarn_state *Y, yarn_int val) // 虚拟机push指令
{
    yarn_uint stk = 0;                                           // 当前栈指针索引
    yarn_incRegister(Y, YARN_REG_STACK, -(int)sizeof(yarn_int)); // 栈增长
    yarn_getRegister(Y, YARN_REG_STACK, &stk);                   // 获取当前增长后的栈指针地址
    yarn_setMemory(Y, stk, &val, sizeof(val));                   // 设置这个地址的值为用户传入的数值
}
// Pops the stack
yarn_int yarn_pop(yarn_state *Y) // 虚拟机pop指令
{
    yarn_uint stk = 0;                                          // 当前栈指针索引
    yarn_int val = 0;                                           // 保存即将出栈的值
    yarn_getRegister(Y, YARN_REG_STACK, &stk);                  // 获取当前栈指针
    yarn_getMemory(Y, stk, &val, sizeof(val));                  // 获取当前栈指针对应内存的值
    yarn_incRegister(Y, YARN_REG_STACK, (int)sizeof(yarn_int)); // 修改栈指针
    return val;                                                 // 返回这个出栈的值
}

// Gets the status of the execution. Status codes are given by YARN_STATUS_
int yarn_getStatus(yarn_state *Y) // 获取虚拟机状态
{
    unsigned char val = 0; // 保存虚拟机状态的变量
    yarn_getMemory(Y, Y->memsize - sizeof(yarn_int), &val, sizeof(val));
    return (int)val; // 返回这个变量
}
void yarn_setStatus(yarn_state *Y, unsigned char val) // 设置虚拟机状态
{
    yarn_setMemory(Y, Y->memsize - sizeof(yarn_int), &val, sizeof(val));
}

// Gets the specified flag. Currently only used for the conditional flag.
int yarn_getFlag(yarn_state *Y, int flag) // 获取标志寄存器
{
    unsigned char val = 0;
    yarn_getMemory(Y, Y->memsize - 3, &val, sizeof(val));
    return (val >> flag) & 1;
}
void yarn_setFlag(yarn_state *Y, int flag) // 设置标志寄存器
{
    unsigned char val = 0;
    yarn_getMemory(Y, Y->memsize - 3, &val, sizeof(val));
    val |= 1 << flag;
    yarn_setMemory(Y, Y->memsize - 3, &val, sizeof(val));
}
void yarn_clearFlag(yarn_state *Y, int flag) // 清除标志寄存器
{
    unsigned char val = 0;
    yarn_getMemory(Y, Y->memsize - 3, &val, sizeof(val));
    val &= ~(1 << flag);
    yarn_setMemory(Y, Y->memsize - 3, &val, sizeof(val));
}

/*
  System call interface, includes helper functions to manipulate the hashmap
*/

static inline unsigned int hash_uint(unsigned int n) // 工具函数，计算hash
{
    return n * 2654435761;
}

void yarn_registerSysCall(yarn_state *Y, yarn_uint key, yarn_CFunc fun) // 注册系统调用
{
    unsigned int n = hash_uint(key);
    for (;;)
    {
        unsigned idx = n & YARN_MAP_MASK;
        if (Y->syscalls[idx].key == key || Y->syscalls[idx].val == NULL)
        {
            Y->syscalls[idx].key = key;
            Y->syscalls[idx].val = fun;
            break;
        }
        n++;
    }
}

yarn_CFunc yarn_getSysCall(yarn_state *Y, yarn_uint key) // 获取系统调用
{
    unsigned n = hash_uint(key);
    for (;;)
    {
        unsigned idx = n & YARN_MAP_MASK;
        if (Y->syscalls[idx].val == NULL)
        {
            return NULL;
        }
        if (Y->syscalls[idx].key == key)
        {
            return Y->syscalls[idx].val;
        }
        n++;
    }
}

/*
 *  External function to execute the program. icount is the maximum number of
 *    instructions to execute. Use -1 to indicate indefinite execution. Will
 *    execute until program sets status to anything but YARN_STATUS_OK,
 */

// 算数指令初始化（有符号的）
// 根据当前IP寄存器的值+1，获取当前的指令，高四位是rA寄存器，低四位是rB寄存器
// 根据当前IP寄存器的值+2，获取操作数
// 将获取到的值保存到valB_s里（有符号）
// 判断rA寄存器的值是否为空
// 如果是则将IP+2的值赋值给valA_s
#define arithinst_s_setup()                \
    yarn_validInstruction(5);              \
    rA = (Y->code[ip + 1] & 0xF0) >> 4;    \
    rB = Y->code[ip + 1] & 0x0F;           \
    d_s = *((yarn_int *)&Y->code[ip + 2]); \
    yarn_getRegister(Y, rB, &valB_s);      \
    if (rA == YARN_REG_NULL)               \
    {                                      \
        valA_s = d_s;                      \
    }                                      \
    else                                   \
    {                                      \
        yarn_getRegister(Y, rA, &valA_s);  \
    }

// 算数指令设置
// valA 保存指令中的值
// valB 保存寄存器中的值
#define arithinst_setup()                 \
    yarn_validInstruction(5);             \
    rA = (Y->code[ip + 1] & 0xF0) >> 4;   \
    rB = Y->code[ip + 1] & 0x0F;          \
    d = *((yarn_uint *)&Y->code[ip + 2]); \
    yarn_getRegister(Y, rB, &valB);       \
    if (rA == YARN_REG_NULL)              \
    {                                     \
        valA = d;                         \
    }                                     \
    else                                  \
    {                                     \
        yarn_getRegister(Y, rA, &valA);   \
    }

// mov指令设置
#define moveinst_setup()                 \
    yarn_validInstruction(5);            \
    rA = (Y->code[ip + 1] & 0xF0) >> 4;  \
    rB = Y->code[ip + 1] & 0x0F;         \
    d = *((yarn_int *)&Y->code[ip + 2]); \
    if (rA == YARN_REG_NULL)             \
    {                                    \
        valA = 0;                        \
    }                                    \
    else                                 \
    {                                    \
        yarn_getRegister(Y, rA, &valA);  \
    }

// 栈指令设置
#define stackinst_setup()     \
    yarn_validInstruction(1); \
    rA = (Y->code[ip + 1] & 0xF0) >> 4;

// 分支指令设置
#define branchinst_setup()    \
    yarn_validInstruction(4); \
    d = *((yarn_int *)&Y->code[ip + 1]);

// 条件指令设置
#define conditionalinst_setup()         \
    yarn_validInstruction(1);           \
    rA = (Y->code[ip + 1] & 0xF0) >> 4; \
    rB = Y->code[ip + 1] & 0x0F;        \
    yarn_getRegister(Y, rA, &valA);     \
    yarn_getRegister(Y, rB, &valB);     \
    yarn_clearFlag(Y, YARN_FLAG_CONDITIONAL);

// 条件指令设置（有符号的）
#define conditionalinst_s_setup()       \
    yarn_validInstruction(1);           \
    rA = (Y->code[ip + 1] & 0xF0) >> 4; \
    rB = Y->code[ip + 1] & 0x0F;        \
    yarn_getRegister(Y, rA, &valA_s);   \
    yarn_getRegister(Y, rB, &valB_s);   \
    yarn_clearFlag(Y, YARN_FLAG_CONDITIONAL);

// debug宏
// 打印当前非法的指令
#ifdef YARN_DEBUG
#define yarn_validInstruction(o)                           \
    if (ip + o >= Y->codesize)                             \
    {                                                      \
        yarn_setStatus(Y, YARN_STATUS_INVALIDINSTRUCTION); \
        printf("INVALID: %d %%ins: 0x%X\n", __LINE__, ip); \
        break;                                             \
    }
#else
#define yarn_validInstruction(o)                           \
    if (ip + o >= Y->codesize)                             \
    {                                                      \
        yarn_setStatus(Y, YARN_STATUS_INVALIDINSTRUCTION); \
        break;                                             \
    }
#endif

// 虚拟机执行指令入口函数
int yarn_execute(yarn_state *Y, int icount)
{
    yarn_uint ip;    // 保存当前栈指针
    int instruction; // 保存当前指令

    while (yarn_getStatus(Y) == YARN_STATUS_OK && (icount > 0 || icount == -1))
    {
        yarn_getRegister(Y, YARN_REG_INSTRUCTION, &ip);
        yarn_validInstruction(0);

        unsigned char rA, rB; //
        yarn_uint valA, valB, valM, d;
        yarn_int valA_s, valB_s, d_s;

        instruction = Y->code[ip];
#if YARN_DEBUG // 如果开启debug宏，则打印相关值
        printf("instruction: 0x%02X icode: 0x%02X\n", instruction, instruction & 0xF0);
#endif

        // Here we execute the specified function for the icode and increment the
        // instruction register.
        switch (instruction) // 根据读取到的指令编码选择指令
        {
        //   Control
        case YARN_INST_HALT: // 停止指令
            yarn_setStatus(Y, YARN_STATUS_HALT);
            yarn_incRegister(Y, YARN_REG_INSTRUCTION, 1);
            break;
        case YARN_INST_PAUSE: // 暂停指令
            yarn_setStatus(Y, YARN_STATUS_PAUSE);
            yarn_incRegister(Y, YARN_REG_INSTRUCTION, 1);
            break;
        case YARN_INST_NOP: // 空指令
            yarn_incRegister(Y, YARN_REG_INSTRUCTION, 1);
            break;

        //   Arith:
        case YARN_INST_ADD: // add指令
            arithinst_setup();                            // 给对应寄存器赋值
            valB += valA;                                 // 将指令中的值与寄存器中的值相加，并赋值给valB
            yarn_setRegister(Y, rB, &valB);               // 将valB写入寄存器rB
            yarn_incRegister(Y, YARN_REG_INSTRUCTION, 6); // 增加指令指针计数器
            break;
        case YARN_INST_SUB: // sub指令
            arithinst_setup();
            valB -= valA;
            yarn_setRegister(Y, rB, &valB);
            yarn_incRegister(Y, YARN_REG_INSTRUCTION, 6);
            break;
        case YARN_INST_MUL: // mul指令
            arithinst_setup();
            valB *= valA;
            yarn_setRegister(Y, rB, &valB);
            yarn_incRegister(Y, YARN_REG_INSTRUCTION, 6);
            break;
        case YARN_INST_DIV: // div指令
            arithinst_setup();
            if (valA == 0) // 除数不能为0，否则报错
            {
                yarn_setStatus(Y, YARN_STATUS_DIVBYZERO);
            }
            else
            {
                valB /= valA;
                yarn_setRegister(Y, rB, &valB);
            }
            yarn_incRegister(Y, YARN_REG_INSTRUCTION, 6);
            break;
        case YARN_INST_DIVS: // 有符号的div指令
            arithinst_s_setup();
            if (valA_s == 0)
            {
                yarn_setStatus(Y, YARN_STATUS_DIVBYZERO);
            }
            else
            {
                valB_s /= valA_s;
                yarn_setRegister(Y, rB, &valB_s);
            }
            yarn_incRegister(Y, YARN_REG_INSTRUCTION, 6);
            break;
        case YARN_INST_LSH: // 左移指令
            arithinst_setup();
            valB <<= valA;
            yarn_setRegister(Y, rB, &valB);
            yarn_incRegister(Y, YARN_REG_INSTRUCTION, 6);
            break;
        case YARN_INST_RSH: // 右移指令
            arithinst_setup();
            valB >>= valA;
            yarn_setRegister(Y, rB, &valB);
            yarn_incRegister(Y, YARN_REG_INSTRUCTION, 6);
            break;
        case YARN_INST_RSHS: // 有符号的右移指令
            arithinst_s_setup();
            valB_s >>= valA_s;
            yarn_setRegister(Y, rB, &valB_s);
            yarn_incRegister(Y, YARN_REG_INSTRUCTION, 6);
            break;
        case YARN_INST_AND: // and 和逻辑运算
            arithinst_setup();
            valB &= valA;
            yarn_setRegister(Y, rB, &valB);
            yarn_incRegister(Y, YARN_REG_INSTRUCTION, 6);
            break;
        case YARN_INST_OR: // or 或逻辑运算
            arithinst_setup();
            valB |= valA;
            yarn_setRegister(Y, rB, &valB);
            yarn_incRegister(Y, YARN_REG_INSTRUCTION, 6);
            break;
        case YARN_INST_XOR: // xor 异或逻辑运算
            arithinst_setup();
            valB ^= valA;
            yarn_setRegister(Y, rB, &valB);
            yarn_incRegister(Y, YARN_REG_INSTRUCTION, 6);
            break;
        case YARN_INST_NOT: // not 非运算
            arithinst_setup();
            valB = ~valA;
            yarn_setRegister(Y, rB, &valB);
            yarn_incRegister(Y, YARN_REG_INSTRUCTION, 6);
            break;

        //   Move:
        case YARN_INST_IR:
            moveinst_setup();
            valA += d;
            yarn_setRegister(Y, rB, &valA);
            yarn_incRegister(Y, YARN_REG_INSTRUCTION, 6);
            break;
        case YARN_INST_MR:
            moveinst_setup();
            yarn_getMemory(Y, d + valA, &valM, sizeof(valM));
            yarn_setRegister(Y, rB, &valM);
            yarn_incRegister(Y, YARN_REG_INSTRUCTION, 6);
            break;
        case YARN_INST_RR:
            moveinst_setup();
            yarn_setRegister(Y, rB, &valA); // Do we want to use d?
            yarn_incRegister(Y, YARN_REG_INSTRUCTION, 6);
            break;
        case YARN_INST_RM:
            moveinst_setup();
            yarn_getRegister(Y, rB, &valB);
            yarn_setMemory(Y, valB + d, &valA, sizeof(valA));
            yarn_incRegister(Y, YARN_REG_INSTRUCTION, 6);
            break;

        //   Stack:
        case YARN_INST_PUSH: // push 指令
            stackinst_setup();
            yarn_getRegister(Y, rA, &valA);
            yarn_push(Y, valA);
            yarn_incRegister(Y, YARN_REG_INSTRUCTION, 2);
            break;
        case YARN_INST_POP: // pop 指令
            stackinst_setup();
            valA = yarn_pop(Y);
            yarn_setRegister(Y, rA, &valA);
            yarn_incRegister(Y, YARN_REG_INSTRUCTION, 2);
            break;

        //   Branches:
        case YARN_INST_CALL: // call指令
            branchinst_setup();
            yarn_push(Y, ip + 5);
            yarn_setRegister(Y, YARN_REG_INSTRUCTION, &d);
            break;
        case YARN_INST_RET: // ret 指令
            branchinst_setup();
            for (yarn_uint i = 0; i < d; i++)
            {
                yarn_pop(Y);
            }
            valA = yarn_pop(Y);
            yarn_setRegister(Y, YARN_REG_INSTRUCTION, &valA);
            break;
        case YARN_INST_JUMP: // jmp 指令
            branchinst_setup();
            yarn_setRegister(Y, YARN_REG_INSTRUCTION, &d);
            break;
        case YARN_INST_CONDJUMP: // 有条件的jmp指令
            branchinst_setup();
            if (yarn_getFlag(Y, YARN_FLAG_CONDITIONAL))
            {
                yarn_setRegister(Y, YARN_REG_INSTRUCTION, &d);
            }
            else
            {
                yarn_incRegister(Y, YARN_REG_INSTRUCTION, 5);
            }
            break;
        case YARN_INST_SYSCALL: // 系统调用指令
            branchinst_setup();
            yarn_CFunc fun = yarn_getSysCall(Y, (yarn_uint)d);
            if (fun == NULL)
            {
                yarn_setStatus(Y, YARN_STATUS_INVALIDINSTRUCTION);
            }
            else
            {
                (*fun)(Y);
            }
            yarn_incRegister(Y, YARN_REG_INSTRUCTION, 5);
            break;

        //   Conditionals:
        case YARN_INST_LT: // 小于关系运算指令
            conditionalinst_setup();
            if (valA < valB)
                yarn_setFlag(Y, YARN_FLAG_CONDITIONAL);
            yarn_incRegister(Y, YARN_REG_INSTRUCTION, 2);
            break;
        case YARN_INST_LTS: // 小于关系运算指令（有符号的）
            conditionalinst_s_setup();
            if (valA_s < valB_s)
                yarn_setFlag(Y, YARN_FLAG_CONDITIONAL);
            yarn_incRegister(Y, YARN_REG_INSTRUCTION, 2);
            break;
        case YARN_INST_LTE: // 小于或等于关系运算指令
            conditionalinst_setup();
            if (valA <= valB)
                yarn_setFlag(Y, YARN_FLAG_CONDITIONAL);
            yarn_incRegister(Y, YARN_REG_INSTRUCTION, 2);
            break;
        case YARN_INST_LTES: // 小于或等于关系运算指令（有符号的）
            conditionalinst_s_setup();
            if (valA_s <= valB_s)
                yarn_setFlag(Y, YARN_FLAG_CONDITIONAL);
            yarn_incRegister(Y, YARN_REG_INSTRUCTION, 2);
            break;
        case YARN_INST_EQ: // 等于关系运算指令
            conditionalinst_setup();
            if (valA == valB)
                yarn_setFlag(Y, YARN_FLAG_CONDITIONAL);
            yarn_incRegister(Y, YARN_REG_INSTRUCTION, 2);
            break;
        case YARN_INST_NEQ: // 不等于关系运算指令
            conditionalinst_setup();
            if (valA != valB)
                yarn_setFlag(Y, YARN_FLAG_CONDITIONAL);
            yarn_incRegister(Y, YARN_REG_INSTRUCTION, 2);
            break;
        default: // 无法匹配的指令
            yarn_setStatus(Y, YARN_STATUS_INVALIDINSTRUCTION);
            break;
        }

        // Check and make sure we haven't run out of instructions to use.
        Y->instructioncount += 1; // 指令计算+1
        if (icount != -1)
        {
            icount -= 1;
        }
    }
    return yarn_getStatus(Y);
}

#undef arithinst_setup
#undef arithinst_s_setup
#undef moveinst_setup
#undef stackinst_setup
#undef branchinst_setup
#undef conditionalinst_setup
#undef conditionalinst_s_setup
#undef yarn_validInstruction

#ifdef YARN_STANDALONE
/*
 * Command line program.
 *   Usage: ./bin/yarn code.o
 *   Flags:
 *     -m<file> - Dumps the memory state to a file. Ex: -mmemdump.mem
 *     -c<icount> - Limits execution to icount instructions. Ex: -c20
 */
inline static void printProgramStatus(yarn_state *Y) // 打印程序状态
{
    printf("Register contents:\n");
    yarn_uint rval = 0;
    for (int r = 0; r < 16; r++)
    {
        yarn_getRegister(Y, r, &rval);
        printf("\tReg: %-5s = 0x%08X   %d\n", yarn_registerToString(r), rval, rval);
    }

    printf("Status: %s\n", yarn_statusToString(yarn_getStatus(Y)));
    printf("Instructions executed: %zu\n", yarn_getInstructionCount(Y));
}

int main(int argc, char **argv) // 虚拟机入口
{
    FILE *fp;                    // 声明一个文件句柄，用于读取文件
    size_t fsize;                // 声明一个获取存即将读取文件大小的无符号变量
    yarn_state *Y;               // 声明虚拟机变量
    char *buffer;                // 声明存储即将读取文件的缓冲区指针
    char *memoryfile = NULL;     // 声明即将要申请的程序内存空间
    int icount = -1;             // 声明要执行的指令条数，默认是-1.表示执行全部指令
    int status = YARN_STATUS_OK; // 声明保存程序运行状态的变量

    if (argc <= 1) // 如果命令行参数小于等于1，说明用户没有明确给出要读取的文件参数，直接报错
    {
        printf("Must specify an object file to load.\n");
        return -1;
    }
    for (int i = 2; i < argc; i++) // 遍历参数个数
    {
        if (strncmp("-m", argv[i], strlen("-m")) == 0) // 如果是带-m的参数并且值不为空
        {
            memoryfile = argv[i] + 2; // 则说明这个参数是用来设置内存文件名的，带程序执行完毕后，会将虚拟机相关数据导出到这个文件里
        }
        else if (strncmp("-c", argv[i], strlen("-c")) == 0)
        {
            icount = atoi(argv[i] + 2); // 该参数用来设置指令多少条指令
        }
    }

    fp = fopen(argv[1], "r"); // 打开用户传入的目标文件
    if (!fp)                  // 打开失败，直接报错
    {
        printf("Invalid object file.\n");
        return EXIT_FAILURE;
    }
    fseek(fp, 0L, SEEK_END); // 找到文件尾部
    fsize = ftell(fp);       // 将获取到的尾部偏移量值赋值给fsize，该变量用来存储当前读取文件的大小
    fseek(fp, 0L, SEEK_SET);

    buffer = malloc(sizeof(char) * fsize); // 根据读取到文件大小，申请对应大小的内存空间
    if (buffer == NULL)                    // 如果申请内存空间失败，直接保存
    {
        printf("Unable to load object file.\n");
        return EXIT_FAILURE;
    }
    fread(buffer, 1, fsize, fp); // 读取文件内容，保存到buffer缓冲区
    fclose(fp);                  // 关闭文件句柄

    Y = yarn_init(256 * sizeof(yarn_int)); // 初始化虚拟机
    if (Y == NULL)                         // 初始虚拟机失败，直接报错
    {
        printf("Unable to create Yarn state.\n");
        return EXIT_FAILURE;
    }
    if (yarn_loadCode(Y, buffer, fsize) != 0) // 加载指令代码
    {
        printf("Unable to load Yarn object code.\n");
        return EXIT_FAILURE;
    }

    while (status == YARN_STATUS_OK) // 当虚拟机状态是OK的，则一致循环执行
    {
        status = yarn_execute(Y, icount); // 执行虚拟机指令，传入虚拟机变量和要执行的指令条数
        printProgramStatus(Y);            // 打印虚拟机状态，用于开发调试用
        if (status == YARN_STATUS_PAUSE)  // 如果虚拟机状态为pause
        {                                 // 则暂停执行
            printf("Program paused, hit enter to continue.");
            getchar(); // 等待用户输入状态
            // Reset our status
            yarn_setStatus(Y, YARN_STATUS_OK); // 继续运行虚拟机
            status = YARN_STATUS_OK;           // 设置虚拟机状态为OK
        }
    }

    if (memoryfile != NULL) // 如果内存文件不为空
    {
        fp = fopen(memoryfile, "w"); // 打开内存文件
        if (!fp)                     // 打开失败，直接报错
        {
            printf("Invalid memory dump name.\n");
            return EXIT_FAILURE;
        }
        fwrite(yarn_getMemoryPtr(Y), 1, yarn_getMemorySize(Y), fp); // 将虚拟机写入内存文件中
        fclose(fp);                                                 // 关闭这个文件
        printf("Wrote memory dump: %s\n", memoryfile);
    }

    yarn_destroy(Y); // 销毁虚拟机
    free(buffer);    // 释放申请的内存
    return 0;
}
#endif
